#include "D3DWindow.h"

#define WINDOW_CLASS "d3d_window"

D3DWindow * D3DWindow::create(const char *title, int width, int height, int x, int y)
{

	// Register the window class
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, D3DWindow::MsgProc, 0L, 0L,
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		WINDOW_CLASS, NULL };
	RegisterClassEx(&wc);

	HWND hWnd = CreateWindow(WINDOW_CLASS, title, WS_OVERLAPPEDWINDOW,
		x, y, width, height, GetDesktopWindow(), NULL,
		wc.hInstance, NULL);

	D3DWindow *pRet = new D3DWindow(hWnd, wc.hInstance);
	if(!pRet->init())
	{
		D3DWindow::destroy(pRet);
		return NULL;
	}
	return pRet;
}

void D3DWindow::destroy(D3DWindow * &pWin)
{
	// Unregister our window.
	UnregisterClass(WINDOW_CLASS, pWin->m_hInstance);
	delete pWin;
	pWin = NULL;
}

bool D3DWindow::init()
{
	m_pRender = new D3DRender();
	return m_pRender->initializeD3d(m_hWnd);
}

D3DWindow::~D3DWindow()
{
	if(m_pRender)
	{
		delete m_pRender;
		m_pRender = NULL;
	}
}

void D3DWindow::start()
{
	// Show the window
	ShowWindow(m_hWnd, SW_SHOWDEFAULT);
	UpdateWindow(m_hWnd);
	
	msgLoop();
}

void D3DWindow::msgLoop()
{
	// Enter the message loop
	MSG msg;
	ZeroMemory(&msg, sizeof(msg));
	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
			render();
	}
}

LRESULT WINAPI D3DWindow::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
		break;
	case WM_KEYUP:
		if(wParam == VK_ESCAPE) PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

void D3DWindow::render()
{
	m_pRender->render();
}